using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Arcadium.Graphics;
using System.Diagnostics;
using Microsoft.Xna.Framework.GamerServices;
using Arcadium.GameEntities.Weapons;
using Microsoft.Xna.Framework.Content;
using Arcadium.Audio;
using Arcadium.GameEntities.Characters;

namespace Arcadium.GameEntities
{
    /// <summary>
    /// A core for a character, with most basic properties.
    /// </summary>
    abstract class Character : GameEntity
    {
        #region Field

        protected Vector2 position;

        #endregion

        #region Properties

        private static long iddistributer;
        public long Id
        {
            get;
            private set;
        }

        public float Health
        {
            get;
            set;
        }
        public Weapon Weapon
        {
            get;
            set;
        }

        public Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }
        public int Direction
        {
            get;
            set;
        }
        
        public Texture2D Texture
        {
            get; private set;
        }
        public Vector2 Origin
        {
            get; private set;
        }
        public int Height
        {
            get { return Texture.Height; }
        }

        #endregion

        #region Initialization
        
        /// <summary>
        /// Constructs a new Character with default values.
        /// </summary>
        public Character(World world) : base(world)
        {
            Id = iddistributer++;
            Health = 1;
            Direction = 1;
        }

        public void SetTexture(CharacterType characterType)
        {
            switch (characterType)
            {
                case CharacterType.Player:
                    Texture = CharacterTextures.PlayerTexture;
                    Origin = CharacterTextures.PlayerTextureOrigin;
                    break;
                case CharacterType.SmallEnemy:
                    Texture = CharacterTextures.SmallEnemyTexture;
                    Origin = CharacterTextures.SmallEnemyTextureOrigin;
                    break;
                case CharacterType.BigEnemy:
                    Texture = CharacterTextures.BigEnemyTexture;
                    Origin = CharacterTextures.BigEnemyTextureOrigin;
                    break;
                case CharacterType.Ghost:
                    break;

                    // TODO: Add more textureasignments

            }
        }

        #endregion

        #region Update & Draw

        public override bool Update(GameTime gameTime)
        {
            return Health <= 0 || (Position.Y > View.ScreenHeight);
        }

        /// <summary>
        /// Draws the character to the spriteBatch.
        /// </summary>
        public override void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(Texture, View.Adjust(Position), null, 
                Color.White, 0, Origin, View.ScreenScale, 
                View.ToEffect(Direction), 0);
            if (Weapon != null)
                Weapon.Draw(spriteBatch);
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Returns a bounding rectangle for this character..
        /// </summary>
        public Rectangle GetBoundingRectangle()
        {
            return GetBoundingRectangle(Position);
        }

        /// <summary>
        /// Returns a bounding rectangle for this character..
        /// </summary>
        public Rectangle GetBoundingRectangle(Vector2 position)
        {
            return new Rectangle(
                (int)Math.Round(position.X - Origin.X),
                (int)Math.Round(position.Y - Origin.Y),
                Texture.Width, Texture.Height);
        }

        /// <summary>
        /// Instantly kills the character.
        /// </summary>
        public void Kill()
        {
            Health = 0;
        }

        public void Harm(float damage)
        {
            Health -= damage;
        }

        #endregion

    }
}
